package com.livestocksolutions.ui;

import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import com.livestocksolutions.Bovine;
import com.livestocksolutions.Group;
import com.livestocksolutions.LivestockSolutions;
import com.livestocksolutions.Location;
import com.livestocksolutions.Mob;
import com.livestocksolutions.Observation;
import com.livestocksolutions.Paddock;
import com.livestocksolutions.util.Comparators;
import com.livestocksolutions.util.JDatePickerDate;
import com.livestocksolutions.util.Table;

/**
 * The Initial view of the application that shows any highly rated Observations.
 * @author Ken DeVries
 * @author Adam Parr
 * 
 * @.modified 19 March 2013
 */
public class HomePanel extends JPanel implements TabbedInterface {
	private static final long serialVersionUID = 1L;

	protected final JPanel panel = new JPanel();
	protected final JPanel search = new JPanel();
	
	/**
	 * Sort the list by Creation Date.
	 */
	protected static final int LIST_ORDER_DATE = 0;
	/**
	 * Sort the list by using the Priority.
	 */
	protected static final int LIST_ORDER_PRIORITY 	= 1;
	/**
	 * Sort the list by using the Type of the Observation Owner.
	 */
	protected static final int LIST_ORDER_TYPE 	= 2;

	/**
	 * The current list order method.
	 * @see #LIST_ORDER_DATE
	 * @see #LIST_ORDER_PRIORITY
	 * @see #LIST_ORDER_TYPE
	 */
	protected int orderListBy = LIST_ORDER_DATE;
	/**
	 * The sort direction. Ascending : 1, Descending -1;
	 */
	protected int orderHighToLow = 1;
	
	/**
	 * Constructor.
	 */
	public HomePanel(){
		JScrollPane jsp = new JScrollPane();
		setLayout(new BorderLayout(0, 0));
		jsp.setViewportView(panel);
		jsp.setViewportBorder(BorderFactory.createEmptyBorder());
		add(jsp);
		
		AdjustmentListener al = new AdjustmentListener(){
			@Override
			public void adjustmentValueChanged(AdjustmentEvent evt) {
				panel.repaint();
			}
		};
		jsp.getHorizontalScrollBar().addAdjustmentListener(al);
		jsp.getVerticalScrollBar().addAdjustmentListener(al);
		
		createSearchPanel();
	}
	
	@Override
	public void displayPanel(){
		createHomePanel();
	}
	
	/**
	 * There is only one possible view.
	 */
	@Override
	public void displayPanel(int panel) {
		createHomePanel();
	}

	/**
	 * Create a list of high priority observations.
	 */
	private void createHomePanel(){
		panel.setLayout(new BorderLayout(0, 0));
		
		final int DATE 		= 0;
		final int DESCRIPTION 	= 1;
		final int PRIORITY 	= 2;
		
		final Table observationPanel = new Table("High Priority Observations",true,
			"Date","Description","Priority","Type");
		observationPanel.setEmptyMessage("There are no High Priority Observations to show.");
		
		new Thread(){
			@Override
			public void run(){
				while(!LivestockSolutions.isReady()){
					try {
						sleep(1000);
					} catch (InterruptedException e) {}
					if(LivestockSolutions.close){
						return;
					}
				}
				
				observationPanel.setHeaderClickable(DESCRIPTION, false);
				observationPanel.setHeaderOrderedBy(orderListBy==LIST_ORDER_DATE?DATE:orderListBy==LIST_ORDER_PRIORITY?PRIORITY:DATE, orderHighToLow==1);
				observationPanel.addHeaderMouseListener(DATE, new MouseListener(){
					@Override
					public void mouseClicked(MouseEvent e) {
						orderHighToLow = orderHighToLow*(orderListBy==LIST_ORDER_DATE?-1:1);
						orderListBy = LIST_ORDER_DATE;
						createHomePanel();
					}
					@Override public void mousePressed(MouseEvent e) {}
					@Override public void mouseReleased(MouseEvent e) {}
					@Override public void mouseEntered(MouseEvent e) {}
					@Override public void mouseExited(MouseEvent e) {}
				});
				observationPanel.addHeaderMouseListener(PRIORITY, new MouseListener(){
					@Override
					public void mouseClicked(MouseEvent e) {
						orderHighToLow = orderHighToLow*(orderListBy==LIST_ORDER_PRIORITY?-1:1);
						orderListBy = LIST_ORDER_PRIORITY;
						createHomePanel();
					}
					@Override public void mousePressed(MouseEvent e) {}
					@Override public void mouseReleased(MouseEvent e) {}
					@Override public void mouseEntered(MouseEvent e) {}
					@Override public void mouseExited(MouseEvent e) {}
				});
				
				Observation[] oList = LivestockSolutions.getObservations();
				ArrayList<Observation> observationArray = new ArrayList<Observation>();
				for(Observation o : oList){
					if(o.getPriority()>Observation.WATCH){
						observationArray.add(o);
					}
				}
				
				oList = observationArray.toArray(new Observation[observationArray.size()]);
				
				Arrays.sort(oList, 
					orderListBy==LIST_ORDER_DATE?
						orderHighToLow==1?Comparators.observationComparatorDate:Collections.reverseOrder(Comparators.observationComparatorDate)
					:orderListBy==LIST_ORDER_PRIORITY?
						orderHighToLow==1?Comparators.observationComparatorPriority:Collections.reverseOrder(Comparators.observationComparatorPriority)
					:orderHighToLow==1?Comparators.observationComparatorOwnerType:Collections.reverseOrder(Comparators.observationComparatorOwnerType));

				for(int x=0; x<oList.length; x++){
					final Object owner = oList[x].getOwner();
					observationPanel.addRow(
						new JLabel(JDatePickerDate.format(oList[x].getDate())),
						new JLabel(oList[x].getComment()),
						new JLabel(Observation.getPriorityString(oList[x].getPriority())),
						new JLabel(owner instanceof Bovine?"Cattle ("+((Bovine)owner).getEartag().getEartagID()+")":owner instanceof Paddock?"Paddock ("+((Location)owner).getName()+")":owner instanceof Location?"Location ("+((Location)owner).getName()+")":owner instanceof Mob?"Mob ("+((Group)owner).getName()+")":owner instanceof Group?"Group ("+((Group)owner).getName()+")":"Unknown"));
					
					observationPanel.addMouseListener(new MouseListener(){
						@Override
						public void mouseClicked(MouseEvent e) {
							if(!(owner instanceof Bovine?MainFrame.getInstance().showBovine(((Bovine)owner).getID()):owner instanceof Paddock?MainFrame.getInstance().showPaddock(((Paddock)owner).getID()):owner instanceof Location?MainFrame.getInstance().showLocation(((Location)owner).getID()):owner instanceof Mob?MainFrame.getInstance().showMob(((Mob)owner).getID()):owner instanceof Group?MainFrame.getInstance().showGroup(((Group)owner).getID()):false)){
								//Show message not found?
							}
						}
						@Override public void mousePressed(MouseEvent e) { }
						@Override public void mouseReleased(MouseEvent e) {}
						@Override public void mouseEntered(MouseEvent e) {}
						@Override public void mouseExited(MouseEvent e) {}
					});
				}
				validate();
			}
		}.start();
		
		if(getComponent(0)!=search){
			add(search, BorderLayout.NORTH);
		}

		panel.removeAll();
		panel.add(observationPanel, BorderLayout.NORTH);
		panel.repaint();
	}
	
	/**
	 * Create the search area of the window.
	 * @return The JPanel that holds the Search area of the window.
	 */
	private JPanel createSearchPanel(){
		search.removeAll();
		search.setLayout(new BorderLayout(0, 0));
		
		JPanel label = new JPanel();
		JLabel lblSearch = new JLabel("Search for Cattle");
		search.add(label, BorderLayout.NORTH);

		lblSearch.setHorizontalAlignment(SwingConstants.CENTER);
		label.add(lblSearch);
		
		JPanel ButtonAndText = new JPanel();
		search.add(ButtonAndText);
		ButtonAndText.setLayout(new BoxLayout(ButtonAndText, BoxLayout.X_AXIS));
		
		final JTextField searchField = new JTextField();
		ButtonAndText.add(searchField);

		searchField.addKeyListener(new KeyListener(){
			@Override
			public void keyTyped(KeyEvent e) {}
			@Override
			public void keyPressed(KeyEvent e) {}
			@Override
			public void keyReleased(KeyEvent e) {
				if(e.getKeyCode()==KeyEvent.VK_ENTER){
					MainFrame.getInstance().doBovineSearch(searchField.getText());
					searchField.setText("");
				}
			}
		});
		
		JButton searchBtn = new JButton("Search");
		ButtonAndText.add(searchBtn);
		searchBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				searchField.setText("");
				MainFrame.getInstance().doBovineSearch(searchField.getText());
			}
		});
		
		return search;
	}

	@Override
	public long getID() {
		return 0;
	}
}
